package NG::Gen::Users::Ladder;
use strict;
use warnings;
use utf8;

#	fields => ['top','pos','level','master','slaves','part',counter'],

sub get_master {
	my $self = shift;
	my $us = $self->{parent}{app}->users;
	return $us->get_by_id($self->ladder->master);
}
sub calc_part_ladder {
	my @t = localtime;
	return ((24 * 60 * 60) - ($t[0] + 60 * ($t[1] + 60 * $t[2]))) / (24 * 60 * 60);
}
sub accept_slave {
	my $self = shift;
	my $slave = shift;
	my $ladder = $self->ladder;
	my $ladder_slave = $slave->ladder;
	if($ladder_slave->master){
		return "Уже есть главный";
	}
	unless($ladder->level > $ladder_slave->level){
		return "Недостаточный уровень";
	}
	my $ary = $ladder->slaves || [];
	unless(@$ary < $self->{parent}{app}->constant->max_slaves){
		return "Все места заняты";
	}
	if(grep {$_ == $slave->obj_id} @$ary){
		return "Уже присутствует";
	}
	push @$ary, $slave->obj_id;
	$ladder->slaves($ary);
	$ladder->has_slaves(@$ary > 0 ? 1 : 0);

	my $top;
	unless($top = $ladder->top){
		$top = $self->obj_id;
		unless($ladder->pos == 1){
			$ladder->pos(1);
		}
	}
	$ladder_slave->top($top);
	$ladder_slave->master($self->obj_id);
	$ladder_slave->pos($ladder->pos + 1);
	$ladder_slave->part(calc_part_ladder());
	$slave->update_ladder;
	return 0;
}
sub leave_master{
	my $self = shift;
	my $ladder = $self->ladder;
	
	unless($ladder->top){
		return "Нет главного";
	}

	my $master = $self->get_master;

	my $ladder_master = $master->ladder;
	my $ary = $ladder_master->slaves || [];
	$ary = [ grep {$_ != $self->obj_id} @$ary ];
	$ladder_master->slaves($ary);
	$ladder_master->has_slaves(@$ary > 0 ? 1 : 0);

	$ladder->top(0);
	$ladder->master(0);
	$ladder->pos(1);
	$self->update_ladder;
	return 0;
}
sub update_ladder {
	my $self = shift;
	my $ladder = $self->ladder;
	my $top;
	unless($top = $ladder->top){
		$top = $self->obj_id;
	}
	my $ary = $ladder->slaves || [];
	my $us = $self->{parent}{app}->users;
	for my $user_id(@$ary){
		my $user = $us->get_by_id($user_id);
		$user->lock_get;
		$user->ladder->top($top);
		$user->ladder->pos($ladder->pos + 1);
		$user->update_ladder;
		$user->lock_free;
	}
}

sub add_ladder {
	my $self = shift;
	my $value = shift;

	my $ladder = $self->ladder;
	$ladder->counter($ladder->counter + $value);
	if($ladder->master){
		my $master = $self->get_master;
		$master->lock_get;
		$master->add_ladder($value);
		$master->lock_free;
	}
}

sub serve_ladder {
	my $self = shift;
	my $value = shift;

	my $ladder = $self->ladder;
	$value = int($ladder->part * $value);
	$ladder->part(1);
	my $was = $ladder->counter;
	$ladder->counter(0);
	my $my_value;
	my $ary = $ladder->slaves || [];
	if(@$ary){
		my $us = $self->{parent}{app}->users;
		$my_value = int($value / 2);
		$value  = int(($value - $my_value) / @$ary);
		for my $user_id(@$ary){
			my $user = $us->get_by_id($user_id);
			$user->lock_get;
			$user->serve_ladder($value);
			$user->lock_free;
		}
	}else{
		$my_value = $value;
	}
	$self->{parent}{app}->logger->notice("served(".$self->title."): $my_value, was: $was");
}

1;
